package org.budo.dubbo.config.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ContextRefreshedEvent;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.ProviderConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;

/**
 * @author lmw
 */
public class DubboServiceConfiger implements ApplicationListener<ApplicationContextEvent> {
    private static final Logger log = LoggerFactory.getLogger(DubboServiceConfiger.class);

    private Class<?>[] interfaceTypes = new Class<?>[0];

    public void onApplicationEvent(ApplicationContextEvent event) {
        if (event instanceof ContextRefreshedEvent) {
            log.info("#26 ContextRefreshedEvent=" + event + ", this=" + this + ", event=" + event);

            this.exportDubboService(event);
        }
    }

    private void exportDubboService(ApplicationContextEvent event) {
        if (null == this.getInterfaceTypes() || this.getInterfaceTypes().length < 1) {
            log.warn("#34 config dubbo service, interfaceTypes is null or empty");
            return;
        }

        ApplicationContext applicationContext = event.getApplicationContext();
        ApplicationConfig applicationConfig = applicationContext.getBean(ApplicationConfig.class);
        ProtocolConfig protocolConfig = applicationContext.getBean(ProtocolConfig.class);
        RegistryConfig registryConfig = applicationContext.getBean(RegistryConfig.class);
        ProviderConfig providerConfig = applicationContext.getBean(ProviderConfig.class);

        for (Class<?> interfaceType : this.getInterfaceTypes()) {
            Object beanInstance = applicationContext.getBean(interfaceType);

            ServiceConfig<Object> serviceConfig = new ServiceConfig<Object>();
            serviceConfig.setApplication(applicationConfig);
            serviceConfig.setProtocol(protocolConfig);
            serviceConfig.setRegistry(registryConfig);
            serviceConfig.setProvider(providerConfig);

            serviceConfig.setInterface(interfaceType);
            serviceConfig.setRef(beanInstance);
            serviceConfig.export();

            log.info("#57 config dubbo service, interfaceType=" + interfaceType + ", beanInstance=" + beanInstance //
                    + ", applicationConfig=" + applicationConfig + ", protocolConfig=" + protocolConfig + ", registryConfig=" + registryConfig + ", providerConfig=" + providerConfig);
        }
    }

    public Class<?>[] getInterfaceTypes() {
        return this.interfaceTypes;
    }

    public void setInterfaceTypes(Class<?>[] interfaceTypes) {
        this.interfaceTypes = interfaceTypes;
    }
}